/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "sle_ssap_server_stub.h"
#include "sle_hilog.h"

namespace OHOS {
namespace NearLink {
namespace SleStandard {
SleSsapServerStub::SleSsapServerStub()
{
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_REGISTER_SERVER] =
        &SleSsapServerStub::RegisterSsapServerInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_UNREGISTER_SERVER] =
        &SleSsapServerStub::UnregisterSsapServerInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_ADD_SERVICE] =
        &SleSsapServerStub::AddServiceInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_ADD_PROPERTY] =
        &SleSsapServerStub::AddPropertyInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_ADD_DESCRIPTOR] =
        &SleSsapServerStub::AddDescriptorInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_REMOVE_ALL_SERVICES] =
        &SleSsapServerStub::RemoveAllServicesInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_START_SERVICE] =
        &SleSsapServerStub::StartServiceInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_SEND_RESPONSE] =
        &SleSsapServerStub::SendResponseInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_NOTIFY_INDICATE] =
        &SleSsapServerStub::NotifyIndicateInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_NOTIFY_INDICATE_BY_UUID] =
        &SleSsapServerStub::NotifyIndicateByUuidInner;
    memberFuncMap_[SleSsapServerInterfaceCode::SLE_SSAP_SERVER_SET_MTU_INFO] =
        &SleSsapServerStub::SetServerMtuInfoInner;
}

SleSsapServerStub::~SleSsapServerStub(){}

int SleSsapServerStub::OnRemoteRequest(
    uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
{
    if (code != SLE_SSAP_SERVER_NOTIFY_INDICATE) {
        SLE_LOGD("cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
    }
    std::u16string descriptor = SleSsapServerStub::GetDescriptor();
    std::u16string remoteDescriptor = data.ReadInterfaceToken();
    SLE_ASSERT_AND_RETURN_RET_LOG(descriptor == remoteDescriptor, ERR_INVALID_STATE, "local descriptor is not equal to remote error!");

    auto itFunc = memberFuncMap_.find((SleSsapServerInterfaceCode)code);
    if (itFunc != memberFuncMap_.end()) {
        auto memberFunc = itFunc->second;
        if (memberFunc != nullptr) {
            return (this->*memberFunc)(data, reply);
        }
    }
    SLE_LOGW("default case, need check.");
    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}

int SleSsapServerStub::RegisterSsapServerInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("RegisterSsapServerInner In");
    std::shared_ptr<Uuid> uuid(data.ReadParcelable<Uuid>());
    SLE_ASSERT_AND_RETURN_RET_LOG(uuid, TRANSACTION_ERR, "read server uuid failed!");

    sptr<IRemoteObject> remote = data.ReadRemoteObject();
    SLE_ASSERT_AND_RETURN_RET_LOG(remote, TRANSACTION_ERR, "read server remote failed!");
    const sptr<ISleSsapServerCallback> callback = OHOS::iface_cast<ISleSsapServerCallback>(remote);
    SLE_ASSERT_AND_RETURN_RET_LOG(callback, TRANSACTION_ERR, "read server callback failed!");

    uint8_t serverId;
    int32_t result = RegisterSsapServer(*uuid, serverId, callback);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteUint8(serverId), TRANSACTION_ERR, "write server id back failed!");
    return NO_ERROR;
}

int SleSsapServerStub::UnregisterSsapServerInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("UnregisterSsapServerInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    sptr<IRemoteObject> remote = data.ReadRemoteObject();
    SLE_ASSERT_AND_RETURN_RET_LOG(remote, TRANSACTION_ERR, "read server remote failed!");
    const sptr<ISleSsapServerCallback> callback = OHOS::iface_cast<ISleSsapServerCallback>(remote);
    SLE_ASSERT_AND_RETURN_RET_LOG(callback, TRANSACTION_ERR, "read server callback failed!");

    int32_t result = UnregisterSsapServer(serverId, callback);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::AddServiceInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("AddServiceInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    std::shared_ptr<Uuid> uuid(data.ReadParcelable<Uuid>());
    SLE_ASSERT_AND_RETURN_RET_LOG(uuid, TRANSACTION_ERR, "read service uuid failed!");

    bool isPrimary;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadBool(isPrimary), TRANSACTION_ERR, "read primary failed!");

    uint16_t handle;
    int32_t result = AddService(serverId, *uuid, isPrimary, handle);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteUint16(handle), TRANSACTION_ERR, "write service handle back failed!");
    return NO_ERROR;
}

int SleSsapServerStub::AddPropertyInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("AddPropertyInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t serviceHandle;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(serviceHandle), TRANSACTION_ERR, "read service handle failed!");

    std::shared_ptr<SsapServerPropertyParam> param(data.ReadParcelable<SsapServerPropertyParam>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read property param failed!");

    uint16_t handle;
    int32_t result = AddProperty(serverId, serviceHandle, *param, handle);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteUint16(handle), TRANSACTION_ERR, "write property handle back failed!");
    return NO_ERROR;
}

int SleSsapServerStub::AddDescriptorInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("AddDescriptorInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t serviceHandle;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(serviceHandle), TRANSACTION_ERR, "read service handle failed!");

    uint16_t propertyHandle;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(propertyHandle), TRANSACTION_ERR, "read property handle failed!");

    std::shared_ptr<SsapServerDescriptorParam> param(data.ReadParcelable<SsapServerDescriptorParam>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read descriptor param failed!");

    int32_t result = AddDescriptor(serverId, serviceHandle, propertyHandle, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::RemoveAllServicesInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("RemoveAllServicesInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    int32_t result = RemoveAllServices(serverId);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::StartServiceInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("StartServiceInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t serviceHandle;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(serviceHandle), TRANSACTION_ERR, "read service handle failed!");

    int32_t result = StartService(serverId, serviceHandle);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::SendResponseInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("SendResponseInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapServerSendRspParam> param(data.ReadParcelable<SsapServerSendRspParam>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read response param failed!");

    int32_t result = SendResponse(serverId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::NotifyIndicateInner(MessageParcel &data, MessageParcel &reply)
{
#if 0
    SLE_LOGD("NotifyIndicateInner In");
#endif
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapServerNotifyParam> param(data.ReadParcelable<SsapServerNotifyParam>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read notify param failed!");

    int32_t result = NotifyIndicate(serverId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::NotifyIndicateByUuidInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("NotifyIndicateByUuidInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint16_t connectId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(connectId), TRANSACTION_ERR, "read connect id failed!");

    std::shared_ptr<SsapServerNotyfyByUuidParam> param(data.ReadParcelable<SsapServerNotyfyByUuidParam>());
    SLE_ASSERT_AND_RETURN_RET_LOG(param, TRANSACTION_ERR, "read notify by uuid param failed!");

    int32_t result = NotifyIndicateByUuid(serverId, connectId, *param);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}

int SleSsapServerStub::SetServerMtuInfoInner(MessageParcel &data, MessageParcel &reply)
{
    SLE_LOGD("SetServerMtuInfoInner In");
    uint8_t serverId;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint8(serverId), TRANSACTION_ERR, "read server id failed!");

    uint32_t mtu;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint32(mtu), TRANSACTION_ERR, "read mtu failed!");

    uint16_t version;
    SLE_ASSERT_AND_RETURN_RET_LOG(data.ReadUint16(version), TRANSACTION_ERR, "read version failed!");

    int32_t result = SetServerMtuInfo(serverId, mtu, version);
    SLE_ASSERT_AND_RETURN_RET_LOG(reply.WriteInt32(result), TRANSACTION_ERR, "write result failed!");
    return NO_ERROR;
}
} // SleStandard
} // NearLink
} // OHOS